//***************************************************
//This is implementation of TPR-tree
//***************************************************

#include <math.h>
#include <time.h>
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include "./rtree/rtree.h"
#include "./rtree/rtnode.h"
#include "./rtree/entry.h"
#include "./blockfile/blk_file.h"
#include "./blockfile/cache.h"
#include "./linlist/linlist.h"

float T=0;

void buildtree(char *_trfname, char *_dsfname, int _dsize, float _T)
{
	printf("really build tree?");
	char c=getchar();
	if (c!='y')
		return;
	remove(_trfname);
	RTree *rt = new RTree(_dsfname, _trfname, _dsize, NULL, _T, 2);
//	rt->adjust_vmbr();
	delete rt;
};

//===========random functions=====================================
float uniform(float _min, float _max)
{
	int int_r = rand();
	long base = RAND_MAX-1;
	float f_r  = ((float) int_r) / base;
	return (_max - _min) * f_r + _min;
}

float new_uniform(int _d_num)
{
	float base=1;
	float sum=0; 
	for (int i=0; i<_d_num; i++)
	{
		int digit=uniform(0, 10);
		if (digit==10) digit=9;
		sum+=base*digit;
		base*=10;
	}
	return sum;
}

float new_uniform(float _min, float _max)
{
	float ran_base=9999999;
	float ran=new_uniform(7);
	return ran/ran_base*(_max-_min)+_min;
}
//================================================================

void RunMain()
{
	printf("*******************************************************\n");
	printf("            expansion TPR-tree indexing Method         \n");  
	printf("*******************************************************\n");
	printf("\n\n");

	int dsize=1024;
	T=50;
	char *trfname="./trees/data10k.tpr";
	/*
	if (argc>1)
		trfname=argv[1];

	if (argc>=1)
		if (argv[0]=="?")
			printf("<indexfile> <datafile>");
		else
			buildtree(trfname, argv[0], dsize, T);
	else */
	buildtree(trfname, "./ds/data10k.txt", dsize, T);
//	char trfname[100]="./trees/up3-2-test.tpr";
//	char trfname[100]="./trees/up3-2.tpr";
//	char trfname[100]="./trees/up3-1a.tpr";
//	char trfname[100]="./trees/up3-2.tpr";
//	char trfname[100]="./trees/testout.tpr";
//	char trfname[100]="./trees/test.tpr";
//	buildtree(trfname, "../../ds/up3-time3.txt", dsize, T);
//	buildtree(trfname, "../../ds/up3-time4.txt", dsize, T);
//	buildtree(trfname, "./ds/up3-time4.txt", dsize, T);
//	buildtree(trfname, "../../ds/testout.txt", dsize, T);
//	buildtree(trfname, "../../ds/la_air_test.txt", dsize, T);
//	traverse_tree(trfname); return;

///*
//	char trfname[100]="./trees/up3-2.tpr";
	float qmbrlen[2]={100, 100};
	float qvbr[4]={-10, 10, -10, 10};
	float qst=0, qed=T;

	Cache *c=new Cache(0, dsize);
	RTree *rt=new RTree(trfname, c);
	printf("queries are performed as of time %.3f\n", rt->time);
	Entry *q=new Entry(2, NULL);

	int ita_cnt=50; 
	int total_rescnt=0;
	for (int i=0; i<ita_cnt; i++)
	{
		q->bounces[0]=new_uniform(1000, 9000-qmbrlen[0]);
		q->bounces[1]=q->bounces[0]+qmbrlen[0];
		q->bounces[2]=new_uniform(1000, 9000-qmbrlen[1]);
		q->bounces[3]=q->bounces[2]+qmbrlen[1];
	
		q->velocity[0]=qvbr[0]; q->velocity[1]=qvbr[1];
		q->velocity[2]=qvbr[2]; q->velocity[3]=qvbr[3];

		int rescnt=0;

		int this_cost=c->page_faults;
		rt->rangeQuery(q, qst, qed, rescnt);
		this_cost=c->page_faults-this_cost;
		total_rescnt+=rescnt;
		printf("%d: cost=%d\n", i+1, this_cost);

		printf("retrieved %d entries\n", rescnt);

	}
	printf("avg # of entries retrieved=%f\n", total_rescnt/(float)ita_cnt);
	printf("avg node accesses=%f\n", c->page_faults/(float)ita_cnt);
	delete q;
	delete rt;
	delete c;
}

void main(int argc, char* argv[])
{
	RunMain();
}

